package gui;



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;


public class ImageHandler implements ImageObserver {
	/** Decides weather or not the ImageHandler should print system messages about what it is doing. Still always prints failures **/
	private static final boolean printingEnabled = false;
	private static ImageHandler me;
	private static int creationCounter = 0;
	
	private List<String> imageNames = new ArrayList<String>();
	private List<BufferedImage> images = new ArrayList<BufferedImage>();
	
	public static ImageHandler getInstance(){
		if (me==null){
			me=new ImageHandler();
			creationCounter++;
			if(printingEnabled)
				System.out.println("Created "+creationCounter+" times");
		}
		
		return me;
	}
	private ImageHandler(){
		loadImages();
	}
	
	/**
	 * Loads all .png images
	 */
	public void loadImages(){
		String iPath=findImagesFolder();
		
		try 
  		{
			for(String s : new File(iPath).list()){
				if(s.endsWith(".png") || s.endsWith(".jpeg") || s.endsWith(".jpg")){
					images.add(bufferImage(iPath+s));	
					imageNames.add(s);
				}	
			}	
			if(printingEnabled)
				System.out.println(images.size()+" images were successfully loaded!");
  		} catch (IOException e) {
  			System.out.println("WARNING! File load error!");
  		} catch (ConcurrentModificationException e){
  			System.out.println("WARNING! ConcurrentModificationException in ImageHandler. Check for solutions on thursday.");
  			System.out.println(e.toString());
  		}
	}
	
	private String findImagesFolder(){
		String[] possiblePaths = {"\\images\\", "images/"};
		for(String iPath : possiblePaths){
			if(printingEnabled)
				System.out.println("trying image path "+iPath);
			if(new File(iPath).isDirectory()){
				if(printingEnabled)
					System.out.println("Path found");
				return iPath;			
			}		
			else if(printingEnabled)
				System.out.println("Path incorrect");
		}
		System.out.println("WARNING: Failed to find correct image path");
  		return "";
		
	}
	
	public List<BufferedImage> getImages(){
		return images;
	}
	
	
	
	public void drawImage(int topLeftX, int topLeftY, int width, int height, String imageName, Graphics g){
		int id = imageNames.indexOf(imageName);
		if(id == -1)
			id = imageNames.indexOf("imageNotFound.png");
		if(id != -1)
			g.drawImage(images.get(id), topLeftX, topLeftY, width, height, this);
	}
	/**
	 * drawn an image ontop of a rectangle with given color, useful for having transparency turn into teamcolor
	 * @param topLeftX
	 * @param topLeftY
	 * @param width
	 * @param height
	 * @param imageName
	 * @param background
	 * @param g
	 */
	public void drawImage(int topLeftX, int topLeftY, int width, int height, String imageName, Color background, Graphics g){
		g.setColor(background);
		g.fillRect(topLeftX, topLeftY, width, height);
		drawImage(topLeftX, topLeftY, width, height, imageName, g);
	}
	
	public Image getImage(String imageName){
		int id = imageNames.indexOf(imageName);
		if(id != -1)
			return images.get(id);
		else
			return getImage("imageNotFound.png");
	}
	public ImageIcon getImageIcon(String imageName){
		return new ImageIcon(getImage(imageName));
	}
	
	
	/**
	 * 
	 * @param filename 
	 * @return
	 * @throws IOException
	 */
	private BufferedImage bufferImage(String filename) throws IOException, ConcurrentModificationException{
		Graphics tg;
		BufferedImage i1=ImageIO.read(new File(filename));
		BufferedImage i2=new BufferedImage(i1.getWidth(), i1.getHeight(), BufferedImage.TYPE_INT_ARGB);//i1.getWidth(null), i1.getHeight(null));
		tg=i2.getGraphics();
		tg.setPaintMode();
		tg.setColor(new Color(0, 0, 0, 0));
		tg.fillRect(0, 0, i1.getWidth(), i1.getHeight());
		tg.drawImage(i1, 0, 0, this);
		return i2;
	}
	@Override
	public boolean imageUpdate(Image arg0, int arg1, int arg2, int arg3,
			int arg4, int arg5) {
		return false;
	}

}
